<?php
declare(strict_types=1);

namespace App\Service;

use App\Utils\CustomUtils;
use Hyperf\Di\Annotation\Inject;
use App\Model\Dao\MchSysNodeDao;
use App\Model\Dao\MchSysAccessDao;
use App\Exception\XZXValidationException;
use App\Constants\XZXResponseCode;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\Arr;
use Hyperf\Utils\Coroutine;
use App\Utils\DateUtils;


class MchSysNodeService {
    /**
     * @Inject()
     * @var MchSysNodeDao
     */
    private $MchSysNodeDao;

    /**
     * @Inject()
     * @var MchSysAccessDao
     */
    private $MchSysAccessDao;

    public function get ($param) {
        $result = $this->MchSysNodeDao->get($param['id']);
        if (!$result) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }
        (isset($result['createTime']) && !empty($result['createTime'])) && $result['createTime'] = DateUtils::getDateTime($result['createTime']);

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $result);
    }

    public function del ($param) {
        $result = $this->MchSysNodeDao->get($param['id']);
        if (!$result) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        try {
            $result = $this->MchSysNodeDao->del($param['id'], false);
        } catch (\Throwable $th) {
            CustomUtils::xzxDebug($th->getMessage());
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DEL_FAIL));
        }
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), CustomUtils::xzxEmptyObject());
    }

    public function add ($param) {
        // TODO: Implement add() method.
        //$data            =  [
        //    'name'       => $param['name'],
        //    'desciption' => $param['desciption'],
        //
        //];
        $data       = $param;
        $data['id'] = CustomUtils::createUUID();
        CustomUtils::xzxDebug($data);

        try {
            $this->MchSysNodeDao->insert($data);
        } catch (\Throwable $th) {
            CustomUtils::xzxDebug($th->getMessage());
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::ADD_FAIL));
        }
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), CustomUtils::xzxEmptyObject());
    }

    public function edit ($param) {
        $info = $this->MchSysNodeDao->get($param['id']);
        if (!$info) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        $id   = $param['id'];
        $data = [];
        // isset($param['name']) && $data['name'] = $param['name'];
        // isset($param['desciption']) && $data['desciption'] = $param['desciption'];

        foreach ($param as $k => $v) {
            if ($k == "id") {
                continue;
            }
            if (isset($v)) {
                $data[$k] = $v;
            }
        }
        CustomUtils::xzxDebug($data);

        try {
            $this->MchSysNodeDao->update($id, $data);
        } catch (\Throwable $th) {
            CustomUtils::xzxDebug($th->getMessage());
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::EDIT_FAIL));
        }
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), CustomUtils::xzxEmptyObject());
    }

    public function list (array $param) {

        $limit = $param['limit'];
        $page  = $param['page'];

        $where = [];

        isset($param['title']) && $where[] = ['title', 'like', '%'.$param['title'].'%'];
        isset($param['status']) && $where[] = ['status', $param['status']];

        $list = $this->MchSysNodeDao->getWhereList($where, [
            'sort'       => 'asc',
            'createTime' => 'desc',
            'id'         => 'asc',
        ]);

        if (!$param['isSuperRole']) {

            // 获取权限关联(这里只有叶子节点)
            $nodeIdList = $this->MchSysAccessDao->getNodeListByRoleId($param['roleId']);
            $nodeIdList = array_column($nodeIdList, 'nodeId');

            $list = $this->_filterList($list, $nodeIdList);
        }

        $data = [
            'total' => 1,
            'list'  => $list,
        ];


        // $total = $this->MchSysNodeDao->getCount($param);
        // $list = $this->MchSysNodeDao->getList($param, $page, $limit);

        // foreach ($list as $k => $v) {
        //     (isset($v['createTime']) && !empty($v['createTime'])) && $v['createTime'] = DateUtils::getDateTime($v['createTime']);
        //     $list[$k] = $v;
        // }

        // $data = array(
        //     'total' => $total,
        //     'list' => $list
        // );

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    protected function _filterList ($list, $nodeIdList) {

        $list = array_column($list, null, 'id');

        // 初始化为不可用
        foreach ($list as $k => $v) {
            $v['status'] = 0;
            $list[$k]    = $v;
        }

        // 遍历nodeIdList
        foreach ($nodeIdList as $nodeId) {
            if (isset($list[$nodeId])) {

                $curr           = &$list[$nodeId];
                $curr['status'] = true;

                while (isset($list[$curr['parentId']])) {
                    $curr           = &$list[$curr['parentId']];
                    $curr['status'] = true;
                }
            }
        }


        // 打印有权限的
        $filterList = [];
        foreach ($list as $k => $v) {
            if ($v['status']) {
                array_push($filterList, $v);
            }
        }

        return $filterList;
    }
}
